﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.IO;

namespace MOSS2007_Wiki_Export
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        string siteUrl;
        string documentLibraryName;
        string rowLimit = "10000";
        string wikiBody;
        string wikiPageName;
        string htmlBody;
        string extention;
        string beforeText;
        string afterText;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnGo_Click(object sender, RoutedEventArgs e)
        {
            if(ParametersSet())
                DoIt();

            
        }

        private bool ParametersSet()
        {
            siteUrl = txtURL.Text;
            documentLibraryName = txtLibraryName.Text;
            int limit;
            if (int.TryParse(txtRowLimit.Text, out limit))
            {
                rowLimit = limit.ToString();
            }
            extention = cmbExt.SelectedValue.ToString();
            beforeText = txtBefore.Text;
            afterText = txtAfter.Text;
            if (!DestinationFolderSet())
            {
                txtOutput.Text += "Please set the destination folder.";
                return false;
            }
            return true;
        }

        private bool DestinationFolderSet()
        {
            if (string.IsNullOrEmpty(txtDestination.Text))
                return false;
            return true;
        }

        private void DoIt()
        {
            StringBuilder updates = new StringBuilder();

            SharePointLists.Lists wsList = new SharePointLists.Lists();
            wsList.Credentials = System.Net.CredentialCache.DefaultCredentials;
            wsList.Url = siteUrl + @"/_vti_bin/lists.asmx";

            // get a list of all top level lists
            XmlNode allLists = wsList.GetListCollection();
            // load into an XML document so we can use XPath to query content
            XmlDocument allListsDoc = new XmlDocument();
            allListsDoc.LoadXml(allLists.OuterXml);
            // allListsDoc.Save(@"c:\allListsDoc.xml"); // for debug
            XmlNamespaceManager ns = new XmlNamespaceManager(allListsDoc.NameTable);
            ns.AddNamespace("d", allLists.NamespaceURI);

            // now get the GUID of the document library we are looking for
            XmlNode dlNode = allListsDoc.SelectSingleNode("/d:Lists/d:List[@Title='" + documentLibraryName + "']", ns);
            if (dlNode == null)
            {
                updates.AppendLine("Document Library " + documentLibraryName + " not found!");
                txtOutput.Text = updates.ToString();
            }
            else
            {
                // obtain the GUID for the document library and the webID
                string documentLibraryGUID = dlNode.Attributes["ID"].Value;
                string webId = dlNode.Attributes["WebId"].Value;

                updates.AppendLine("Opening folder " + documentLibraryName + " GUID=" + documentLibraryGUID);
                txtOutput.Text = updates.ToString();

                // create ViewFields CAML
                XmlDocument viewFieldsDoc = new XmlDocument();
                XmlNode ViewFields = AddXmlElement(viewFieldsDoc, "ViewFields", "");
                AddFieldRef(ViewFields, "GUID");
                AddFieldRef(ViewFields, "ContentType");
                AddFieldRef(ViewFields, "BaseName");
                AddFieldRef(ViewFields, "Modified");
                AddFieldRef(ViewFields, "EncodedAbsUrl");
                AddFieldRef(ViewFields, "WikiField");
                AddFieldRef(ViewFields, "LinkFilename");
                //viewFieldsDoc.Save(@"c:\viewFields.xml"); // for debug

                // create QueryOptions CAML
                XmlDocument queryOptionsDoc = new XmlDocument();
                XmlNode QueryOptions = AddXmlElement(queryOptionsDoc, "QueryOptions", "");
                AddXmlElement(QueryOptions, "Folder", documentLibraryName);
                AddXmlElement(QueryOptions, "IncludeMandatoryColumns", "FALSE");
                // this element is the key to getting the full recusive list
                XmlNode node = AddXmlElement(QueryOptions, "ViewAttributes", "");
                AddXmlAttribute(node, "Scope", "Recursive");
                queryOptionsDoc.Save(@"c:\queryOptions.xml"); // for debug

                //Create Query CAML
                XmlDocument queryDoc = new XmlDocument();
                XmlNode Query = AddXmlElement(queryDoc, "Query", "");

                // obtain the list of items in the document library
                XmlNode listContent = wsList.GetListItems(documentLibraryGUID, null, Query, ViewFields, rowLimit, QueryOptions, webId);

                XmlDocument xmlResultsDoc = new XmlDocument();
                xmlResultsDoc.LoadXml(listContent.OuterXml);
                ns = new XmlNamespaceManager(xmlResultsDoc.NameTable);
                ns.AddNamespace("z", "#RowsetSchema");
                // xmlResultsDoc.Save(@"c:\listContent.xml"); // for debug

                XmlNodeList rows = xmlResultsDoc.SelectNodes("//z:row", ns);
                if (rows.Count == 0)
                {
                    updates.AppendLine("No content found");
                    txtOutput.Text = updates.ToString();

                }
                foreach (XmlNode row in rows)
                {
                    htmlBody = beforeText;

                    wikiPageName = txtDestination.Text + "\\" + row.Attributes.GetNamedItem("ows_LinkFilename").Value.Replace(".aspx", "."+cmbExt.Text);
                    wikiBody = row.Attributes.GetNamedItem("ows_WikiField").Value;

                    htmlBody += wikiBody;
                    htmlBody += afterText;
                    WriteFile(wikiPageName, wikiBody);

                }
            }
            updates.AppendLine("Done");
            txtOutput.Text = updates.ToString();
        }

        private void WriteFile(string name, string body)
        {
            StreamWriter sw = new StreamWriter(name);
            sw.WriteLine(htmlBody);
            sw.Close();
        }

        public static XmlNode AddXmlElement(XmlNode parent, string elementName, string elementValue)
        {
            XmlNode element = parent.AppendChild(parent.OwnerDocument.CreateNode(XmlNodeType.Element, elementName, ""));
            if (elementValue != "")
                element.InnerText = elementValue;
            return (element);
        }

        public static XmlNode AddXmlElement(XmlDocument parent, string elementName, string elementValue)
        {
            XmlNode element = parent.AppendChild(parent.CreateNode(XmlNodeType.Element, elementName, ""));
            if (elementValue != "")
                element.InnerText = elementValue;
            return (element);
        }

        public static XmlNode AddXmlAttribute(XmlNode element, string attrName, string attrValue)
        {
            XmlNode attr = element.Attributes.Append((XmlAttribute)element.OwnerDocument.CreateNode(XmlNodeType.Attribute, attrName, ""));
            if (attrValue != "")
                attr.Value = attrValue;
            return (attr);
        }

        public static void AddFieldRef(XmlNode viewFields, string fieldName)
        {
            XmlNode fieldRef = AddXmlElement(viewFields, "FieldRef", "");
            AddXmlAttribute(fieldRef, "Name", fieldName);
        }

        private void btnBrowse_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();

            // Show open file dialog box
            dlg.ShowDialog();

            // Process open file dialog box results
            if (!string.IsNullOrEmpty(dlg.SelectedPath))
            {
                // Open document
                txtDestination.Text = dlg.SelectedPath;
            }

        }

    }
}
